/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
File Name          : usb_prop.c
Author             : MCD Application Team
Version            : V3.2.1
Date               : 07/05/2010
Description        : All processings related to Custom HID Demo
********************************************************************************
THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#include "usb_lib.h"
#include "usb_conf.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "usb.h"

uint32_t ProtocolValue;

extern  uint8_t  usbplug;

DEVICE Device_Table={
	EP_NUM,
	1
};
DEVICE_PROP Device_Property={
	CustomHID_init,
	CustomHID_Reset,
	CustomHID_Status_In,
	CustomHID_Status_Out,
	CustomHID_Data_Setup,
	CustomHID_NoData_Setup,
	CustomHID_Get_Interface_Setting,
	CustomHID_GetDeviceDescriptor,
	CustomHID_GetConfigDescriptor,
	CustomHID_GetStringDescriptor,
	0,
	0x40 /*MAX PACKET SIZE*/
};
USER_STANDARD_REQUESTS User_Standard_Requests ={
    CustomHID_GetConfiguration,
    CustomHID_SetConfiguration,
    CustomHID_GetInterface,
    CustomHID_SetInterface,
    CustomHID_GetStatus,
    CustomHID_ClearFeature,
    CustomHID_SetEndPointFeature,
    CustomHID_SetDeviceFeature,
    CustomHID_SetDeviceAddress
};
ONE_DESCRIPTOR Device_Descriptor ={
	(uint8_t*)CustomHID_DeviceDescriptor,
	CUSTOMHID_SIZ_DEVICE_DESC
};
ONE_DESCRIPTOR Config_Descriptor ={
	(uint8_t*)CustomHID_ConfigDescriptor,
	CUSTOMHID_SIZ_CONFIG_DESC
};
ONE_DESCRIPTOR CustomHID_Report_Descriptor ={
	(uint8_t *)CustomHID_ReportDescriptor,
	CUSTOMHID_SIZ_REPORT_DESC
};
ONE_DESCRIPTOR CustomHID_Hid_Descriptor ={
	(uint8_t*)CustomHID_ConfigDescriptor + CUSTOMHID_OFF_HID_DESC,
	CUSTOMHID_SIZ_HID_DESC
};
ONE_DESCRIPTOR String_Descriptor[4] ={
	{(uint8_t*)CustomHID_StringLangID, CUSTOMHID_SIZ_STRING_LANGID},
	{(uint8_t*)CustomHID_StringVendor, CUSTOMHID_SIZ_STRING_VENDOR},
	{(uint8_t*)CustomHID_StringProduct, CUSTOMHID_SIZ_STRING_PRODUCT},
	{(uint8_t*)CustomHID_StringSerial, CUSTOMHID_SIZ_STRING_SERIAL}
};
/*******************************************************************************
* Function Name  : CustomHID_init.
* Description    : Custom HID init routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CustomHID_init(void){
	usb_serialNum();// Update the serial number string descriptor with the data
					// from the unique ID
	pInformation->Current_Configuration=0;
	PowerOn();		// Connect the device
	USB_SIL_Init();	// Perform basic device initialization operations
	bDeviceState = UNCONNECTED;
}
/*******************************************************************************
* Function Name  : CustomHID_Reset.
* Description    : Custom HID reset routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CustomHID_Reset(void){
	// Set Joystick_DEVICE as not configured
	pInformation->Current_Configuration = 0;
	pInformation->Current_Interface = 0;	// the default Interface
	// Current Feature initialization
	pInformation->Current_Feature = CustomHID_ConfigDescriptor[7];
	SetBTABLE(BTABLE_ADDRESS);
	// Initialize Endpoint 0
	SetEPType(ENDP0, EP_CONTROL);
	SetEPTxStatus(ENDP0, EP_TX_STALL);
	SetEPRxAddr(ENDP0, ENDP0_RXADDR);
	SetEPTxAddr(ENDP0, ENDP0_TXADDR);
	Clear_Status_Out(ENDP0);
	SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
	SetEPRxValid(ENDP0);
	// Initialize Endpoint 1
	SetEPType(ENDP1, EP_INTERRUPT);
	SetEPRxAddr(ENDP1, ENDP1_RXADDR);
	SetEPRxCount(ENDP1, 64);
	SetEPRxStatus(ENDP1, EP_RX_VALID);
	// Initialize Endpoint 2
	SetEPType(ENDP2, EP_INTERRUPT);
	SetEPTxAddr(ENDP2, ENDP2_TXADDR);
	SetEPTxCount(ENDP2, 64);
	SetEPTxStatus(ENDP2, EP_TX_NAK);
	// Set this device to response on default address
	SetDeviceAddress(0);
	bDeviceState = ATTACHED;
}
/*******************************************************************************
* Function Name  : CustomHID_SetConfiguration.
* Description    : Udpade the device state to configured.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CustomHID_SetConfiguration(void){
	if (pInformation->Current_Configuration != 0){
		// Device configured
		bDeviceState = CONFIGURED;
		//usbplug=1;
	}
}
/*******************************************************************************
* Function Name  : CustomHID_SetConfiguration.
* Description    : Udpade the device state to addressed.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CustomHID_SetDeviceAddress(void){
	bDeviceState = ADDRESSED;
}
/*******************************************************************************
* Function Name  : CustomHID_Status_In.
* Description    : Joystick status IN routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CustomHID_Status_In(void){
}
/*******************************************************************************
* Function Name  : CustomHID_Status_Out
* Description    : Joystick status OUT routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CustomHID_Status_Out (void){
}
RESULT CustomHID_Data_Setup(uint8_t RequestNo){
	// Handle the data class specific requests.
	uint8_t *(*CopyRoutine)(uint16_t);
	CopyRoutine = NULL;
	if((RequestNo==GET_DESCRIPTOR)&&
		(Type_Recipient==(STANDARD_REQUEST | INTERFACE_RECIPIENT))&&
		(pInformation->USBwIndex0==0)){
		// GET_DESCRIPTOR
		if(pInformation->USBwValue1 == REPORT_DESCRIPTOR)
			CopyRoutine = CustomHID_GetReportDescriptor;
		else if(pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE)
			CopyRoutine = CustomHID_GetHIDDescriptor;
	}else if((Type_Recipient==(CLASS_REQUEST|INTERFACE_RECIPIENT))&&
		RequestNo==GET_PROTOCOL)
		// GET_PROTOCOL
		CopyRoutine=CustomHID_GetProtocolValue;
	if(CopyRoutine == NULL)
		return USB_UNSUPPORT;
	pInformation->Ctrl_Info.CopyData=CopyRoutine;
	pInformation->Ctrl_Info.Usb_wOffset=0;
	(*CopyRoutine)(0);
	return USB_SUCCESS;
}
/*******************************************************************************
* Function Name  : CustomHID_NoData_Setup
* Description    : handle the no data class specific requests
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
RESULT CustomHID_NoData_Setup(uint8_t RequestNo){
	if((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))&&
		(RequestNo == SET_PROTOCOL))
		return CustomHID_SetProtocol();
	else return USB_UNSUPPORT;
}
/*******************************************************************************
* Function Name  : CustomHID_GetDeviceDescriptor.
* Description    : Gets the device descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the device descriptor.
*******************************************************************************/
uint8_t *CustomHID_GetDeviceDescriptor(uint16_t Length){
	return Standard_GetDescriptorData(Length, &Device_Descriptor);
}
/*******************************************************************************
* Function Name  : CustomHID_GetConfigDescriptor.
* Description    : Gets the configuration descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
uint8_t *CustomHID_GetConfigDescriptor(uint16_t Length){
	return Standard_GetDescriptorData(Length, &Config_Descriptor);
}
/*******************************************************************************
* Function Name  : CustomHID_GetStringDescriptor
* Description    : Gets the string descriptors according to the needed index
* Input          : Length
* Output         : None.
* Return         : The address of the string descriptors.
*******************************************************************************/
uint8_t *CustomHID_GetStringDescriptor(uint16_t Length){
	uint8_t wValue0 = pInformation->USBwValue0;
	if(wValue0 > 4)
		return NULL;
	else return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
}
/*******************************************************************************
* Function Name  : CustomHID_GetReportDescriptor.
* Description    : Gets the HID report descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
uint8_t *CustomHID_GetReportDescriptor(uint16_t Length){
	return Standard_GetDescriptorData(Length, &CustomHID_Report_Descriptor);
}
/*******************************************************************************
* Function Name  : CustomHID_GetHIDDescriptor.
* Description    : Gets the HID descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
uint8_t *CustomHID_GetHIDDescriptor(uint16_t Length){
	return Standard_GetDescriptorData(Length, &CustomHID_Hid_Descriptor);
}
/*******************************************************************************
* Function Name  : CustomHID_Get_Interface_Setting.
* Description    : tests the interface and the alternate setting according to the
*                  supported one.
* Input          : - Interface : interface number.
*                  - AlternateSetting : Alternate Setting number.
* Output         : None.
* Return         : USB_SUCCESS or USB_UNSUPPORT.
*******************************************************************************/
RESULT CustomHID_Get_Interface_Setting(uint8_t Interface,
	uint8_t AlternateSetting){
	if(AlternateSetting>0)
		return USB_UNSUPPORT;
	else if(Interface>0)
		return USB_UNSUPPORT;
	return USB_SUCCESS;
}
RESULT CustomHID_SetProtocol(void){
	// Joystick Set Protocol request routine.
	uint8_t wValue0 = pInformation->USBwValue0;
	ProtocolValue = wValue0;
	return USB_SUCCESS;
}
uint8_t *CustomHID_GetProtocolValue(uint16_t Length){
	// get the protocol value
	if (Length == 0){
		pInformation->Ctrl_Info.Usb_wLength = 1;
		return NULL;
	}else return (uint8_t *)(&ProtocolValue);
}